#include "time.h"
#include <stdio.h>
#include <string.h>

#ifdef WIN32
#include <windows.h>
static LARGE_INTEGER freq;
static LARGE_INTEGER start;
static LARGE_INTEGER stop;
#endif

#ifdef __linux
#include <sys/time.h>
#include <errno.h>
// #include <time.h>
#include <stdexcept>
static struct timeval start_time;
struct timeval now_time;
static bool initialized = false;
#endif

#ifdef __APPLE__
#include <sys/time.h>
#include <errno.h>
#include <stdexcept>
static struct timeval start_time;
struct timeval now_time;
static bool initialized = false;
#endif

#include <iostream>
using namespace std;

void Time::Start() {
#ifdef WIN32
	QueryPerformanceFrequency(&freq);
	QueryPerformanceCounter(&start);
#endif

#ifdef __linux
	initialized=true;
	if(gettimeofday(&start_time, 0) != 0)
		throw std::runtime_error(std::string("gettimeofday failed: ") + strerror(errno));
#endif
#ifdef __APPLE__
	initialized=true;
	if(gettimeofday(&start_time, 0) != 0)
		throw std::runtime_error(std::string("gettimeofday failed: ") + strerror(errno));
#endif
}

void Time::Stop() {
#ifdef WIN32
	QueryPerformanceCounter(&stop);
#endif

#ifdef __linux
	if(!initialized)
		initialized = true;
	if(gettimeofday(&now_time, 0) != 0)
		throw std::runtime_error(std::string("gettimeofday failed: ") + strerror(errno));
#endif
#ifdef __APPLE__
	if(!initialized)
		initialized = true;
	if(gettimeofday(&now_time, 0) != 0)
		throw std::runtime_error(std::string("gettimeofday failed: ") + strerror(errno));
#endif
}

double Time::GetTime() {
#ifdef WIN32
	return (double)((stop.QuadPart - start.QuadPart)) / freq.QuadPart; 
#endif

#ifdef __linux
	return (now_time.tv_sec-start_time.tv_sec)+(now_time.tv_usec-start_time.tv_usec)*1.e-6;
#endif
#ifdef __APPLE__
	return (now_time.tv_sec-start_time.tv_sec)+(now_time.tv_usec-start_time.tv_usec)*1.e-6;
#endif
}

#if 0
#include "Time.h"
#include <sys/time.h>
#include <errno.h>
#ifdef __linux
#include <time.h>
#endif
#include <stdexcept>

static struct timeval start_time;
static bool initialized = false;

void
Time::initialize()
{
  initialized=true;
  if(gettimeofday(&start_time, 0) != 0)
    throw std::runtime_error(std::string("gettimeofday failed: ")
                             +strerror(errno));
}

double Time::currentSeconds()
{
  if(!initialized)
    initialized = true;
  struct timeval now_time;
  if(gettimeofday(&now_time, 0) != 0)
    throw std::runtime_error(std::string("gettimeofday failed: ")
                             +strerror(errno));
  return (now_time.tv_sec-start_time.tv_sec)+(now_time.tv_usec-start_time.tv_usec)*1.e-6;
}
#endif
